在《現行深度學習架構概況》一文中,我們不斷地提到了計算圖的設計,而讓深度學習的架構朝向兩個不同的方向發展:一個是以 PyTorch 為主的動態計算圖,另一個則是以 Tensorflow 為主的靜態計算圖。
而計算圖對深度學習,或是幾乎等同於同義的類神經網路實踐可以先由類神經網路的訓練方法來討論。
類神經網路的訓練,有兩個步驟:
第一個步驟是正向傳播(forward propagation),就是將訓練資料餵送給類神經網路,隨著層層疊起的網路結構,往上攀爬,最後到達最上層的輸出神經元,輸出預測結果並和真正的輸出,透過損失函示做比較,得到與期望相差的損失值。
第二個步驟則是反向傳播(back propagation),目的在將正向傳播後計算出的誤差值,以反向回溯的方式,藉由梯度計算連鎖規則(chain rule)由上而下更新每一層的參數值。而更新的方法則是計算該層參數對誤差的個別貢獻,若以數學式表現,則是對誤差取各層參數的微分。
這些在類神經網路的架構中,正向或反向間穿梭的數值,正是利用前所述的自動微分計算圖來執行。而根據計算圖如何在程式中執行,計算圖又可分為動態計算圖(dynamic computational graph)和靜態計算圖(static computational graph)。
所謂的動態計算圖,也就是目前深度學習的趨勢,包括 PyTorch 和 Apache MXNet Gluon 模組都採用此類的方式來建構計算圖。在動態計算圖中,圖的整個結構無需再一開始就必須建構好,透過追蹤程式的執行方式來動態執行,所以又被稱為執行期間的自動微分(runtime autodiff)。這樣的方式有利於直譯式語言,去動態執行計算圖中的每一個子圖中的運算,並及時得到運算的結果。
動態計算圖圖片出處
而靜態或又稱為符號式計算圖,則需要開發者在執行前先將所有的計算圖子圖都建構好,所以又被稱為事先自動微分(ahead-of-time audodiff),在這個分類之下包括了 Google 的 Tensorflow 和 MXNet Module 模組。
靜態計算題圖片出處
相較於動態計算圖,除了比較難用,除錯不容易外,靜態符號試計算圖,有以下優點:
在實作上, tensorflow 真正的計算核心是和 python 直譯器分開來的,也因如此在真正執行的時候,需要一個 Session 的物件來與計算核心溝通,並在這個 Session 餵以計算核心資料,並透過 Session 來做除錯。然而,缺乏動態除錯的方式,造成了許多研究者,還在實驗性階段,嘗試不同的類神經網路模型,或最佳化演算法時,使用直譯式語言,如 Python,除錯上的困難,也因此失去了 Python 這種動態語言,在快速建立實驗性原型時的優點。
接下來我們會以使用者的角度對 PyTorch 和 Tensorflow 兩個著名的深度學習框架來做介紹。